package com.cmc.cloud.cmclink.doc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.lock.annotation.Lock4j;
import com.cmc.cloud.cmclink.doc.constants.errorconstant.SpecialCargoApplyErrorCodeConstants;
import com.cmc.cloud.cmclink.doc.convert.SuperWhitelistDgConvert;
import com.cmc.cloud.cmclink.doc.entity.SuperWhitelistDgDO;
import com.cmc.cloud.cmclink.doc.mapper.SuperWhitelistDgMapper;
import com.cmc.cloud.cmclink.doc.service.SuperWhitelistDgService;
import com.cmc.cloud.cmclink.doc.vo.superwhitelistvo.*;
import com.cmc.cloud.cmclink.system.api.api.file.FileApi;
import com.cmes.framework.common.exception.util.ServiceExceptionUtil;
import com.cmes.framework.common.pojo.CommonResult;
import com.cmes.framework.common.pojo.PageResult;
import com.cmes.framework.mybatis.core.query.LambdaQueryWrapperX;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;


/**
 * 有条件接载清单(DG) Service 实现类
 *
 * @author 集运管理员
 */
@Service
@Validated
public class SuperWhitelistDgServiceImpl implements SuperWhitelistDgService {

    @Resource
    private SuperWhitelistDgMapper superWhitelistDgMapper;

    @Resource
    private FileApi fileApi;

    @Override
    public void createSuperWhitelistDg(SuperWhitelistDgBaseVO createReqVO) {
        // 插入
        LambdaQueryWrapperX<SuperWhitelistDgDO> queryWrapperX = new LambdaQueryWrapperX<SuperWhitelistDgDO>()
                .eqIfPresent(SuperWhitelistDgDO::getSpecialCargoType, createReqVO.getSpecialCargoType())
                .eqIfPresent(SuperWhitelistDgDO::getPraNo, createReqVO.getPraNo());
        List<SuperWhitelistDgDO> whitelistDgDos = superWhitelistDgMapper.selectList(queryWrapperX);
        if (CollectionUtil.isNotEmpty(whitelistDgDos)) {
            throw ServiceExceptionUtil.exception(SpecialCargoApplyErrorCodeConstants.SUPER_WHITELIST_OOG_ERROR);
        }
        SuperWhitelistDgDO superWhitelistDg = SuperWhitelistDgConvert.INSTANCE.convert(createReqVO);
        superWhitelistDgMapper.insert(superWhitelistDg);
    }

    @Override
    public void updateSuperWhitelistDg(SuperWhitelistDgUpdateReqVO updateReqVO) {
        // 更新
        SuperWhitelistDgDO updateObj = SuperWhitelistDgConvert.INSTANCE.convert(updateReqVO);
        superWhitelistDgMapper.updateById(updateObj);
    }

    @Override
    public void deleteSuperWhitelistDg(Long id) {
        // 删除
        superWhitelistDgMapper.deleteById(id);
    }

    @Override
    public SuperWhitelistDgDO getSuperWhitelistDg(Long id) {
        return superWhitelistDgMapper.selectById(id);
    }

    @Override
    public List<SuperWhitelistDgDO> getSuperWhitelistDgList(Collection<Long> ids) {
        return superWhitelistDgMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<SuperWhitelistDgDO> getSuperWhitelistDgPage(SuperWhitelistDgPageReqVO reqVO) {
        LambdaQueryWrapperX<SuperWhitelistDgDO> queryWrapperX = new LambdaQueryWrapperX<SuperWhitelistDgDO>()
                .eqIfPresent(SuperWhitelistDgDO::getSpecialCargoType, reqVO.getSpecialCargoType())
                .eqIfPresent(SuperWhitelistDgDO::getPraNo, reqVO.getPraNo())
                .eqIfPresent(SuperWhitelistDgDO::getPors, reqVO.getPors())
                .eqIfPresent(SuperWhitelistDgDO::getPols, reqVO.getPols())
                .eqIfPresent(SuperWhitelistDgDO::getPods, reqVO.getPods())
                .eqIfPresent(SuperWhitelistDgDO::getDels, reqVO.getDels());
        return superWhitelistDgMapper.selectPage(reqVO, queryWrapperX);
    }

    @Override
    public List<SuperWhitelistDgDO> getExportList(SuperWhitelistReqVO reqVO) {
        LambdaQueryWrapperX<SuperWhitelistDgDO> dgQuery = new LambdaQueryWrapperX<SuperWhitelistDgDO>()
                .eqIfPresent(SuperWhitelistDgDO::getSpecialCargoType, reqVO.getSpecialCargoType())
                .likeIfPresent(SuperWhitelistDgDO::getPraNo, reqVO.getPraNo())
                .likeIfPresent(SuperWhitelistDgDO::getPors, reqVO.getPors())
                .likeIfPresent(SuperWhitelistDgDO::getPols, reqVO.getPols())
                .likeIfPresent(SuperWhitelistDgDO::getPods, reqVO.getPods())
                .likeIfPresent(SuperWhitelistDgDO::getDels, reqVO.getDels());
        return superWhitelistDgMapper.selectList(dgQuery);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void copyFromHistory(SpecialWhiteListCopyReqVO originalVo) {
        //复制源主数据
        SuperWhitelistDgDO originalWhiteDgInfo = superWhitelistDgMapper.selectById(originalVo.getOriginalId());
        if (null == originalWhiteDgInfo) {
            throw ServiceExceptionUtil.exception(SpecialCargoApplyErrorCodeConstants.SPECIAL_CARGO_APPLY_NOT_EXISTS);
        }
        SuperWhitelistDgDO newApply = new SuperWhitelistDgDO();
        BeanUtil.copyProperties(originalWhiteDgInfo, newApply, "createTime", "updateTime", "creator", "updater");
        newApply.setId(null);
        superWhitelistDgMapper.insert(newApply);
    }

    @Override
    public Integer saveImportData(List<SuperWhitelistDgBaseVO> importVos) {
        //将集合分成2000一组 去保存
        int batchSize = 2000;
        List<List<SuperWhitelistDgBaseVO>> partitions = IntStream.range(0, (importVos.size() + batchSize - 1) / batchSize)
                .mapToObj(i -> importVos.subList(i * batchSize, Math.min(batchSize * (i + 1), importVos.size())))
                .collect(Collectors.toList());
        partitions.forEach(partition -> {
                    // 处理每个子集合

                    List<SuperWhitelistDgDO> dgList = BeanUtil.copyToList(partition, SuperWhitelistDgDO.class);
                    superWhitelistDgMapper.saveOrUpdateBatch(dgList);
                }
        );
        return importVos.size();
    }

    @Override
    @Lock4j(name = "dgDeleteFile", keys = {"#id"})
    public void deleteFile(Long id) {
        SuperWhitelistDgDO superWhitelistDgDO = superWhitelistDgMapper.selectById(id);
        if (superWhitelistDgDO == null) {
            throw ServiceExceptionUtil.exception(SpecialCargoApplyErrorCodeConstants.SPECIAL_CARGO_APPLY_NOT_EXISTS);
        }
        if (superWhitelistDgDO.getFileId() == null) {
            throw ServiceExceptionUtil.exception(SpecialCargoApplyErrorCodeConstants.SPECIAL_CARGO_CNTR_FILE_NOT_EXISTS);
        }
        CommonResult<Boolean> result = fileApi.delete(superWhitelistDgDO.getFileId());
        if(result.isError()){
            throw ServiceExceptionUtil.exception(SpecialCargoApplyErrorCodeConstants.SPECIAL_CARGO_CNTR_FILE_DELETE_ERROR);
        }
        superWhitelistDgDO.setFileId(null);
        superWhitelistDgMapper.updateById(superWhitelistDgDO);

    }
}
